﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;

namespace TaDMS.Models
{
    public interface IRepository<T> : IDisposable where T : class
    {
        /// <summary>
        /// Gets all objects from database
        /// </summary>
        /// <param name="total">Return total records</param>
        /// <param name="filter">Specified a filter</param>
        /// <param name="orderBy">Specified a order</param>
        /// <param name="multiFilter">Multi specified a filter</param>
        /// <param name="includeProperties">Entities to include into query</param>
        /// <param name="isPaging">Paging Data</param>
        /// <param name="start">The page index. Default value: 0</param>
        /// <param name="limit">The page size. Default value: 50</param>
        /// <returns>IEnumerable type</returns>
        IEnumerable<T> GetData(out int? total,
                               Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, 
                               Expression<Func<T, bool>> filter = null,
                               IList<Expression<Func<T, bool>>> multiFilter = null,
                               string includeProperties = "",
                               Boolean isPaging = false,
                               int start = 0,
                               int limit = 50);

        /// <summary>
        /// Gets the object(s) is exists in database by specified filter.
        /// </summary>
        /// <param name="predicate">Specified the filter expression</param>
        bool? Contains(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Find object by specified expression.
        /// </summary>
        /// <param name="predicate"></param>
        T Find(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Create a new object to database.
        /// </summary>
        /// <param name="t">Specified a new object to create.</param>
        T Create(T t);

        /// <summary>
        /// Create news object to database.
        /// </summary>
        /// <param name="t">Specified a new object to create.</param>
        int? Create(List<T> t);

        /// <summary>
        /// Delete the object from database.
        /// </summary>
        /// <param name="t">Specified a existing object to delete.</param>        
        int? Delete(T t);

        /// <summary>
        /// Delete objects from database by specified filter expression.
        /// </summary>
        /// <param name="predicate"></param>
        int? Delete(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Update object changes and save to database.
        /// </summary>
        /// <param name="t">Specified the object to save.</param>
        int? Update(T t);
        
        /// <summary>
        /// Update object changes and save to database.
        /// </summary>
        /// <param name="t">Specified the object to save.</param>
        /// <param name="fields">List field to edit</param>
        int? Update(T t, string fields);
    }
}